/**
	TODO 
		inject loading structure
		wait (bool)
*/

var FogManager = new Class({
	
	Implements: [Options, Events],

	options: {
		onStartOpen: $empty(), // au lancement de l'ouverture
		onCompleteOpen: $empty(), // a l'ouverture complete
		onStartClose: $empty(), // au lancement de la fermeture
		onCompleteClose: $empty(), // a la fermeture complete
		duration: 200, // duree anim
		styles: false, // objet de style pour le fog
		locked: false, // a tres, empeche la fermeture du layer au clic 
		noAnimation: false, // n'effectue pas d'effet de fondu,
		setTo: null, // element sur lequel positionner le layer , defaut <body>
		loading: false, 
		keepClose: false, // ne pas ouvrir le layer (pour une ouverture manuelle)
		name : "", // nom de l'element, sert dans FogBox.js
		ie6FixedPosition: true, // simule le position:fixed sur ie (gourmand setInterval)
		content: null, // node | string html
		iframeSrc: null,
		iframeStyles: {},
		ajaxText: null,
		ajaxJSON: null,
		template: null,
			/** template a utliser avec 
				substitute pour JSON
				<div id="FOG_CONTENT"></div> dans le template, sera remplace apr le conteny
				replace __CONTENT__ avec HTML
			*/
		objectData: null,
		ajaxNoCache: false,
		ajaxOptions: null // option de l'object Request a utiliser, ne pas modifier le onComplete ou le onSuccess
	},
	
	setContent: function (content){
		this.contentType = $type(content);
		switch(this.contentType){
			case "element":
				if(this.options.template){
					var d = new Element("div", {"html": this.options.template});
					$(document.body).adopt(d);
					content.replaces($('FOG-CONTENT'));
					this.ctnElement = d;
				}
				else {
					this.ctnElement = content;
					$(document.body).adopt(this.ctnElement);
				}
				break;
			case "object":
				this.ctnElement = new Element("div", {"html": this.options.template.substitute(content), "class": "layer hidden"});
				$(document.body).adopt(this.ctnElement);
				break;
			case "string":
				if(this.options.template){
					this.ctnElement = new Element("div", {"html": this.options.template.replace(/__FOGCONTENT__/, content)});
				}
				else {
					this.ctnElement = new Element("div", {"html": content});
				}
				$(document.body).adopt(this.ctnElement);
				break;
				
		}
		if(!this.ctnElement.hasClass("layer") && !this.ctnElement.getElement(".layer")) this.ctnElement.addClass("layer");
		if(!this.options.keepClose) this.open();

	},
	
	initialize : function (options){
		this.setOptions(options)
		
		// ferme par defaut
		this.isOpen = false;
		this.onDom = false;
		// creation de la structure
		this.elm = new Element("div", {'class': 'fog hidden'});
		this.elm.store("FogManager", this);
		// ifr pour ie6
		if(Browser.Engines.trident && Browser.Engine.version <= 4){
			this.ifr = new Element('iframe');
			this.ifr.src = "javascript:false";
			$(document.body).adopt(this.ifr);
		}
		$(document.body).adopt(this.elm);
		this.get_CSS_style();
		this.elm.setStyles(this.options.styles);
		
		// recuperation du contenu
		switch(true){
			case this.options.ajaxText != null:
				new Request({
					url: this.options.ajaxText, 
					noCache: this.options.ajaxNoCache,
					onSuccess: 	
						function (oSelf){
							return function(responseText, responseXML){
								oSelf.setContent(responseText);
							}
						}(this)
					}).send();
				break;
			case this.options.ajaxJSON != null:
				new Request.JSON({
					url: this.options.ajaxJSON, 
					noCache: this.options.ajaxNoCache,
					onSuccess: 	
						function (oSelf){
							return function(responseJSON, responseText){
								oSelf.setContent(responseJSON);
							}
						}(this)
					}).send();
				break;
			case this.options.objectData != null:
				this.setContent(this.options.objectData);
				break;
			case this.options.content != null:
				if($type(this.options.content) == "element") {
					this.onDom = true;
					this.options.template = null;
				}
				this.setContent(this.options.content);
				break;
			case this.options.iframeSrc != null:
				this.setContent(new Element('iframe', {'src': this.options.iframeSrc}).setStyles(this.options.iframeStyles));
				break;
			default:
				if(this.options.loading) this.wait(true);
				this.onDom = true;
				this.open();
		}
		
		
		// au resize, on repositionne
		Notifier.addEvent("onLayoutChanged", function (){
			this.setToElm(this.lastElm);
		}.bind(this))
		
		window.addEvent("resize", function (){
			this.setToElm(this.lastElm);
		}.bind(this))
		
		// fermeture definitive
		this.addEvent('onCompleteClose', 
			function (){
				// destruction
				if(!this.elm) return;
				this.isOpen = false;
				this.elm.dispose();
				if(!this.onDom) this.ctnElement.dispose();
				if(this.interval) clearInterval(this.interval);
				if(this.ifr) this.ifr.dispose();
			}
		)
		
		if(!this.options.locked) this.elm.addEvent('click', function (){this.close();}.bind(this));
		else {
			this.elm.setStyle("cursor", "default");
		}
	},
	
	get_CSS_style: function (){
		if(!this.options.styles) this.options.styles = {};
		if(!this.options.styles.backgroundColor) this.options.styles.backgroundColor = this.elm.getStyle("backgroundColor");
		if(!this.options.styles.opacity) this.options.styles.opacity = this.elm.getCSS('opacity');
	},
    
  toggle: function(){
		this.isOpen == true ? this.close() : this.open();
  },
    
  open: function (){
		this.fireEvent("onStartOpen", [this, this.elm]);
		this.setToElm();
		
		if(this.options.noAnimation) {
			this.elm.removeClass('hidden');
			this.ctnElement.removeClass('hidden');
			this.ctnElement.setStyle("marginLeft", -this.ctnElement.offsetWidth/2)
			this.ctnElement.setStyle("marginTop", -this.ctnElement.offsetHeight/2)
			this.ctnElement.setStyle("opacity", "1")
			this.ctnElement.getElements(".layerClose").addEvent("click", function (e){e.stop();this.close();}.bind(this))
			this.fireEvent("onCompleteOpen", [this, this.elm]);
			return;
		}
		
		if(this.ctnElement){
			elm = $(this.ctnElement);
			
			try {elm.getElements(".layerClose").addEvent("click", function (e){e.stop();this.close();}.bind(this))}
			catch(e){}
			
			// ajout de l'anim sur le ctn
			this.currentContent = elm;
			var myFx2 = new Fx.Tween(elm, {
				onStart: function (){
					this.element.removeClass("hidden");
					this.element.setStyle("marginLeft", -this.element.offsetWidth/2);
					this.element.setStyle("marginTop", -this.element.offsetHeight/2);
				},
				duration: this.options.duration
			});
			myFx2.set("opacity", "0");
			myFx2.start("opacity", "1");
			this.fixTopPosition();
		}
		else {
			this.currentContent = null;
		}
		
		var _self = this;
		// ouverture du fog
		var myFx = new Fx.Tween(this.elm, {
			onStart: function (){
				
				this.elm.removeClass("hidden");
				
			}.bind(this),
			onComplete: function (){
				this.fireEvent("onCompleteOpen", [this, this.elm]);
				this.isOpen = true;
				//this.createIfr();
			}.bind(this),
			duration: this.options.duration
		});
		myFx.set("opacity", "0");
		myFx.start("opacity", this.options.styles.opacity);
	},
	
	close: function (){
		this.wait(false);
		
		if(this.options.noAnimation) {
			this.fireEvent("onCompleteClose", [this, this.elm]);
			return;
		}
		
		// fermeture du fog
		var myFx = new Fx.Tween(this.elm, {
			onStart: function (){
				this.fireEvent("onStartClose", [this, this.elm]);
			}.bind(this),
			onComplete: function (){
				this.fireEvent("onCompleteClose", [this, this.elm]);
			}.bind(this),
			duration: this.options.duration + 10
		});
		myFx.set("opacity", this.options.styles.opacity);
		myFx.start("opacity", "0");
		
		if(this.ctnElement){
			var myFx2 = new Fx.Tween($(this.ctnElement), {
				onStart: function (){}.bind(this),
				onComplete: function (){
				}.bind(this),
				duration: this.options.duration
			});
			myFx2.set("opacity", "1");
			myFx2.start("opacity", "0");
		}
	},
	
	setToElm: function (){
		
		if(this.options.setTo && $(this.options.setTo)){
			var coo = $(this.options.setTo).getCoordinates();
			this.elm.setStyles({
				"width": coo.width,
				"height": coo.height,
				"top": coo.top,
				"left": coo.left})
		}
		else {
			var w = Math.max(document.body.scrollWidth, document.documentElement.clientWidth);
			var h = Math.max(document.body.scrollHeight, document.documentElement.clientHeight);
			if(!this.options.styles.width || !this.options.styles.width === 0) this.elm.setStyle('width', w)
			if(!this.options.styles.height ||!this.options.styles.height === 0) this.elm.setStyle('height', h)
			if(!this.options.styles.top ||!this.options.styles.top === 0) this.elm.setStyle('top', 0)
			if(!this.options.styles.left ||!this.options.styles.left === 0) this.elm.setStyle('left', 0)
		}
		if(Browser.Engines.trident && Browser.Engine.version <= 4){
			this.ifr.setStyles({
				"width": document.body.scrollWidth,
				"height": document.body.scrollHeight,
				"top": 0,
				"left": 0,
				"zIndex": 998,
				"position": "absolute",
				"filter": "mask()",
				"visibility": "visible"
				})
		}
	},
	
	fixTopPosition: function (){
		if(Browser.Engine.trident4){
			var wHeight = document.documentElement.clientHeight;
			this.interval = setInterval(function (oSelf){
				return function (){
						oSelf.currentContent.setStyle("marginTop", document.documentElement.scrollTop + (wHeight / 2) - (oSelf.currentContent.offsetHeight/2))
				}
			}(this), 1);
		}
	},
	
	strToNode: function (str){
		var div = new Element('div', {"html": str});
		return div.getFirst();
	},
	
	wait: function (bool){
		if(bool){
			this.elm.adopt(new Element('div', {'class': 'fogSpinner'}));
		}
		else {
			this.elm.getElements('.fogSpinner').each(function (el){
				el.dispose();
			})
		}
		return this;
	}
});